package com.cygsunri.ess.api;

import com.alibaba.fastjson.JSON;
import com.cygsunri.common.constant.DataName;
import com.cygsunri.common.entity.ConfigConstant;
import com.cygsunri.common.service.CommonDataService;
import com.cygsunri.ess.vo.JidianEssBaseResponse;
import com.cygsunri.ess.vo.JidianEssChart;
import com.cygsunri.measurement.entity.Flag;
import com.cygsunri.measurement.entity.MeasurementValue;
import com.cygsunri.scada.base.BasePSR;
import com.cygsunri.scada.service.ScadaPSRService;
import com.cygsunri.util.*;
import com.github.abel533.echarts.Option;
import com.github.abel533.echarts.axis.CategoryAxis;
import com.github.abel533.echarts.series.Bar;
import com.github.abel533.echarts.series.Line;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.net.URI;
import java.util.*;

/**
 * 储能页api
 */
@RestController
@RequestMapping("/api/ess")
public class EssController {

    @Value("${corsair.yc.step}")
    private Integer ycStep;

    @Autowired
    private ScadaPSRService scadaPSRService;

    @Autowired
    private CommonDataService commonDataService;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private ConfigConstant configConstant;

    /**
     * 储能soc和效率
     *
     * @param id 储能PSRID
     */
    @RequestMapping(value = "/charts/brief/substations/{id}", method = RequestMethod.GET)
    public ResponseEntity<List<MeasurementValue>> brief(@PathVariable("id") String id) {
        List<MeasurementValue> measurementValues = new ArrayList<>();
        BasePSR basePSR = scadaPSRService.getDeviceByPsrId(id);
        MeasurementValue p = commonDataService.getValueFillDisPlay(basePSR.getId(), DataName.TOTAL_ACTIVE_POWER);
        MeasurementValue soc = commonDataService.getValueFillDisPlay(basePSR.getId(), DataName.SOC);
        MeasurementValue efficiency = commonDataService.getValueFillDisPlay(basePSR.getId(), DataName.EFFICIENCY);

        measurementValues.add(p);
        measurementValues.add(soc);
        measurementValues.add(efficiency);
        return new ResponseEntity<>(measurementValues, HttpStatus.OK);
    }

    /**
     * 储能每日充放电量
     *
     * @param id   储能PSRID
     * @param from 开始时间
     * @param to   结束时间
     */
    @RequestMapping(value = "/charts/statistics/kwh/substations/{id}/{from}/{to}", method = RequestMethod.GET)
    public ResponseEntity<String> statisticsKwh(@PathVariable("id") String id, @PathVariable("from") String from, @PathVariable("to") String to) {
        Option option = new Option();
        CategoryAxis categoryAxis = new CategoryAxis();
        option.xAxis(categoryAxis);

        Bar charge = new Bar("充电量");
        option.series(charge);

        Bar discharge = new Bar("放电量");
        option.series(discharge);

        BasePSR substation = scadaPSRService.getDeviceByPsrId(id);
        if (substation == null) {
            return new ResponseEntity<>(JSON.toJSONString(option), HttpStatus.NOT_FOUND);
        }

        List<String> dates = DateUtil.getDays(from, to);
        for (String date : dates) {
            categoryAxis.data(date);

            MeasurementValue dayCharge = commonDataService.getValue(id, DataName.TOTAL_CHARGE, TimeUtil.toMilliSeconds(date), Flag.DAY_DIFF);
            charge.data(dayCharge.isInValid() ? "-" : dayCharge.getData());

            MeasurementValue dayDischarge = commonDataService.getValue(id, DataName.TOTAL_DISCHARGE, TimeUtil.toMilliSeconds(date), Flag.DAY_DIFF);
            discharge.data(dayDischarge.isInValid() ? "-" : dayDischarge.getData());
        }

        return new ResponseEntity<>(JSON.toJSONString(option), HttpStatus.OK);
    }

    /**
     * 储能功率曲线
     *
     * @param id   储能PSRID
     * @param date 日期
     */
    @RequestMapping(value = "/charts/power/substations/{id}/dates/{date}", method = RequestMethod.GET)
    public ResponseEntity<String> power(@PathVariable("id") String id, @PathVariable("date") String date) {
        Option option = new Option();
        CategoryAxis categoryAxis = new CategoryAxis();
        option.xAxis(categoryAxis);

        Line currentLine = new Line();
        option.series(currentLine);

        Line beforeLine = new Line();
        option.series(beforeLine);

        List<MeasurementValue> currentValues = commonDataService.getHistoryValue(id, DataName.TOTAL_ACTIVE_POWER, date.trim() + " 00:00", date.trim() + " 24:00", ycStep, 2, false);
        boolean hasX = false;
        if (!currentValues.isEmpty()) {
            hasX = true;
            for (MeasurementValue today : currentValues) {
                categoryAxis.data(today.getTime());
                currentLine.data(today.isInValid() ? "-" : today.getData());
            }
        }

        String before = DateUtil.beforeDay(date);
        List<MeasurementValue> beforeValues = commonDataService.getHistoryValue(id, DataName.TOTAL_ACTIVE_POWER, before.trim() + " 00:00", before.trim() + " 24:00", ycStep, 2, false);
        for (MeasurementValue m : beforeValues) {
            if (!hasX) {
                categoryAxis.data(m.getTime());
            }
            beforeLine.data(m.isInValid() ? "-" : m.getData());
        }
        return new ResponseEntity<>(JSON.toJSONString(option), HttpStatus.OK);
    }

    /**
     * 储能SOC曲线
     *
     * @param id   储能PSRID
     * @param date 日期
     */
    @RequestMapping(value = "/charts/soc/substations/{id}/dates/{date}", method = RequestMethod.GET)
    public ResponseEntity<String> soc(@PathVariable("id") String id, @PathVariable("date") String date) {
        Option option = new Option();
        CategoryAxis categoryAxis = new CategoryAxis();
        option.xAxis(categoryAxis);

        Line currentSoc = new Line();
        option.series(currentSoc);

        Line beforeSoc = new Line();
        option.series(beforeSoc);

        List<MeasurementValue> currentValues = commonDataService.getHistoryValue(id, DataName.SOC, date.trim() + " 00:00", date.trim() + " 24:00", ycStep, 2, false);
        boolean hasX = false;
        if (!currentValues.isEmpty()) {
            hasX = true;
            for (MeasurementValue today : currentValues) {
                categoryAxis.data(today.getTime());
                currentSoc.data(today.isInValid() ? "-" : today.getData());
            }
        }

        String before = DateUtil.beforeDay(date);
        List<MeasurementValue> beforeValues = commonDataService.getHistoryValue(id, DataName.SOC, before.trim() + " 00:00", before.trim() + " 24:00", ycStep, 2, false);
        for (MeasurementValue m : beforeValues) {
            if (!hasX) {
                categoryAxis.data(m.getTime());
            }
            beforeSoc.data(m.isInValid() ? "-" : m.getData());
        }
        return new ResponseEntity<>(JSON.toJSONString(option), HttpStatus.OK);
    }

    /**
     * 储能今日功率曲线
     *
     */
    @RequestMapping(value = "/charts/power/substations/today", method = RequestMethod.GET)
    public ResponseEntity<String> power() {
        Option option = new Option();
        CategoryAxis categoryAxis = new CategoryAxis();
        option.xAxis(categoryAxis);

        Line currentLine = new Line();
        option.series(currentLine);

        //签名
        Long timestamp = DateUtil.nowSeconds();
        String str_1 = String.format("timestamp=%s&app_key=%s", timestamp.toString(), configConstant.getEssAccess_key_id());
        String str_2 = HMACUtil.hmacDigestMD5(str_1, configConstant.getEssAccess_key_secret());
        String str_3 = String.format("%s&signature=%s", str_1, str_2);
        String signature = Base64Util.convert(str_3);

        //构建消息头
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.valueOf("application/json;UTF-8"));
        httpHeaders.add("Signature", signature); //签名

        //请求参数
        Map<String, Object> params = new HashMap<>();
        params.put("start_time", DateUtil.startOfTodaySeconds());
        params.put("end_time", DateUtil.nowSeconds());

        URI chartUri = UrlParametersUtil.handleUrlParameters(configConstant.getEssGetDeviceChartByTimeUrl(), params);

        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(null, httpHeaders);

        ResponseEntity<JidianEssBaseResponse> exchange = restTemplate.exchange(chartUri, HttpMethod.GET, requestEntity, JidianEssBaseResponse.class);
        JidianEssBaseResponse jidianEssBaseResponse = exchange.getBody();
        LinkedHashMap<String, Object> data = jidianEssBaseResponse != null ? jidianEssBaseResponse.getData() : null;
        List list = (List)(data != null ? data.get("statistics") : null);

        for (int i = 0; i < list.size(); i++) {
            LinkedHashMap<String, Object> statistics = (LinkedHashMap<String, Object>) list.get(i);
            currentLine.data((Integer)statistics.get("Pdc") / 1000.0);
        }

        for (int i = 0; i < 144 - list.size(); i++) {
            currentLine.data("-");
        }

        for (String s : DateUtil.getTenMinutes()) {
            categoryAxis.data(s);
        }

        return new ResponseEntity<>(JSON.toJSONString(option), HttpStatus.OK);
    }

}
